home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 6 / CU Amiga Magazine's Super CD-ROM 06 (1996)(EMAP Images)(GB)(Track 1 of 4)[!][issue 1997-01].iso / cucd / prog / gnu-c / src / gcc-2.7.0-amiga / config / 1750a / 1750a.c next >
C/C++ Source or Header  |  1995-06-15  |  14KB  |  580 lines

  1. /* Subroutines for insn-output.c for MIL-STD-1750.
  2.    Copyright (C) 1994, 1995 Free Software Foundation, Inc.
  3.    Contributed by O.M.Kellogg, DASA (okellogg@salyko.cube.net).
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 1, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 59 Temple Place - Suite 330,
  20. Boston, MA 02111-1307, USA.  */
  21.  
  22. #ifndef FILE
  23. #include <stdio.h>
  24. #endif
  25. #include <string.h>
  26.  
  27. #define __datalbl
  28. #include "config.h"
  29. #include "rtl.h"
  30. #include "tree.h"
  31. #include "expr.h"
  32. #define HAVE_cc0
  33. #include "conditions.h"
  34. #include "real.h"
  35.  
  36. struct datalabel_array datalbl[DATALBL_ARRSIZ];
  37. int datalbl_ndx = -1;
  38. struct jumplabel_array jmplbl[JMPLBL_ARRSIZ];
  39. int jmplbl_ndx = -1;
  40. int label_pending = 0, program_counter = 0;
  41. enum section current_section = Normal;
  42. char *sectname[4] =
  43. {"Init", "Normal", "Konst", "Static"};
  44.  
  45. int
  46. notice_update_cc (exp)
  47.      rtx exp;
  48. {
  49.   if (GET_CODE (exp) == SET)
  50.     {
  51.       enum rtx_code src_code = GET_CODE (SET_SRC (exp));
  52.       /* Jumps do not alter the cc's.  */
  53.       if (SET_DEST (exp) == pc_rtx)
  54.     return;
  55.       /* Moving register into memory doesn't alter the cc's.
  56.      It may invalidate the RTX's which we remember the cc's came from.  */
  57.       if (GET_CODE (SET_DEST (exp)) == MEM)
  58.     {
  59.       if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
  60.         cc_status.value1 = 0;
  61.       if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
  62.         cc_status.value2 = 0;
  63.       return;
  64.     }
  65.       /* Function calls clobber the cc's.  */
  66.       else if (src_code == CALL)
  67.     {
  68.       CC_STATUS_INIT;
  69.       return;
  70.     }
  71.       /* Emulated longword bit-ops leave cc's incorrect */
  72.       else if (GET_MODE (SET_DEST (exp)) == HImode ?
  73.            src_code == AND || src_code == IOR ||
  74.            src_code == XOR || src_code == NOT : 0)
  75.     {
  76.       CC_STATUS_INIT;
  77.       return;
  78.     }
  79.       /* Tests and compares set the cc's in predictable ways.  */
  80.       else if (SET_DEST (exp) == cc0_rtx)
  81.     {
  82.       CC_STATUS_INIT;
  83.       cc_status.value1 = SET_SRC (exp);
  84.       return;
  85.     }
  86.       /* Anything that lands in a reg will set cc_status. */
  87.       else if (REG_P (SET_DEST (exp)))
  88.     {
  89.       cc_status.flags = CC_NO_OVERFLOW;
  90.       cc_status.value1 = SET_SRC (exp);
  91.       cc_status.value2 = SET_DEST (exp);
  92.       return;
  93.     }
  94.       else
  95.     {
  96.       CC_STATUS_INIT;
  97.     }
  98.     }
  99.   else if (GET_CODE (exp) == PARALLEL
  100.        && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
  101.     {
  102.       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
  103.     return;
  104.       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
  105.     {
  106.       CC_STATUS_INIT;
  107.       cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
  108.       return;
  109.     }
  110.       CC_STATUS_INIT;
  111.     }
  112.   else
  113.     {
  114.       CC_STATUS_INIT;
  115.     }
  116. }
  117.  
  118.  
  119. rtx
  120. function_arg (cum, mode, type, named)
  121.      int cum;
  122.      enum machine_mode mode;
  123.      tree type;
  124.      int named;
  125. {
  126.   int size;
  127.   rtx result;
  128.  
  129.   if (MUST_PASS_IN_STACK (mode, type))
  130.     return (rtx) 0;
  131.   if (mode == BLKmode)
  132.     size = int_size_in_bytes (type);
  133.   else
  134.     size = GET_MODE_SIZE (mode);
  135.   if (cum + size < 12)
  136.     return gen_rtx (REG, mode, cum);
  137.   else
  138.     return (rtx) 0;
  139. }
  140.  
  141.  
  142. #ifndef STRDUP
  143. char *
  144. strdup (str)
  145.      char *str;
  146. {
  147.   char *p;
  148.   if (str == NULL)
  149.     return NULL;
  150.   if ((p = (char *) malloc (strlen (str) + 1)) == NULL)
  151.     {
  152.       fprintf (stderr, "dynamic memory exhausted");
  153.       abort ();
  154.     }
  155.   return strcpy (p, str);
  156. }
  157.  
  158. #endif
  159.  
  160.  
  161. double
  162. get_double (x)
  163.      rtx x;
  164. {
  165.   union
  166.     {
  167.       double d;
  168.       long i[2];
  169.     }
  170.   du;
  171.  
  172.   du.i[0] = CONST_DOUBLE_LOW (x);
  173.   du.i[1] = CONST_DOUBLE_HIGH (x);
  174.   return du.d;
  175. }
  176.  
  177. char *
  178. float_label (code, value)
  179.      char code;
  180.      double value;
  181. {
  182.   int i = 1;
  183.   static char label[32];
  184.   char *p;
  185.  
  186.   label[0] = code;
  187.   p = label + 1;
  188.   sprintf (p, "%lf", value);
  189.   while (*p)
  190.     {
  191.       *p = (*p == '+') ? 'p' :
  192.     (*p == '-') ? 'm' : *p;
  193.       p++;
  194.     }
  195.   return strdup (label);
  196. }
  197.  
  198.  
  199. char *
  200. movcnt_regno_adjust (op)
  201.      rtx *op;
  202. {
  203.   static char outstr[40];
  204.   int cntreg = REGNO (op[2]), cntreg_1750 = REGNO (op[0]) + 1;
  205.   int dstreg = REGNO (op[0]), srcreg = REGNO (op[1]);
  206.  
  207.   if (cntreg == cntreg_1750)
  208.     sprintf (outstr, "mov r%%0,r%%1");
  209.   else if (dstreg + 1 == srcreg && srcreg == cntreg + 2)
  210.     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,r%%1", cntreg, dstreg);
  211.   else if (dstreg + 1 == srcreg && srcreg < cntreg)
  212.     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,r%%1", srcreg, cntreg);
  213.   else if (srcreg + 1 == cntreg && dstreg > cntreg)
  214.     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,r%%1", srcreg, dstreg);
  215.   else
  216.     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,%%1\n\txwr r%d,r%d",
  217.          cntreg, cntreg_1750, cntreg_1750, cntreg);
  218.   return outstr;
  219. }
  220.  
  221. char *
  222. mod_regno_adjust (instr, op)
  223.      char *instr;
  224.      rtx *op;
  225. {
  226.   static char outstr[40];
  227.   char *r = (!strncmp (instr, "dvr", 3) ? "r" : "");
  228.   int modregno_gcc = REGNO (op[3]), modregno_1750 = REGNO (op[0]) + 1;
  229.  
  230.   if (modregno_gcc == modregno_1750)
  231.     sprintf (outstr, "%s r%%0,%s%%2", instr, r);
  232.   else
  233.     sprintf (outstr, "lr r%d,r%d\n\t%s r%%0,%s%%2\n\txwr r%d,r%d",
  234.     modregno_gcc, modregno_1750, instr, r, modregno_1750, modregno_gcc);
  235.   return outstr;
  236. }
  237.  
  238.  
  239. /* Auxiliary to `nonindirect_operand':
  240.    Check if op is a valid memory operand for 1750A arith./logic (non-move)
  241.    instructions. */
  242. int
  243. memop_valid (op)
  244.      rtx op;
  245. {
  246.   if (GET_MODE (op) != Pmode && GET_MODE (op) != VOIDmode)
  247.     return 0;
  248.   switch (GET_CODE (op))
  249.     {
  250.     case MEM:
  251.     case MINUS:
  252.     case MULT:
  253.     case DIV:
  254.       return 0;
  255.     case PLUS:
  256.       if (!memop_valid (XEXP (op, 0)))
  257.     return 0;
  258.       return memop_valid (XEXP (op, 1));
  259.     case REG:
  260.       if (REGNO (op) > 0)
  261.     return 1;
  262.       return 0;
  263.     case CONST:
  264.     case CONST_INT:
  265.     case SYMBOL_REF:
  266.     case SUBREG:
  267.       return 1;
  268.     default:
  269.       printf ("memop_valid: code=%d\n", (int) GET_CODE (op));
  270.       return 1;
  271.     }
  272. }
  273.  
  274. /* extra predicate for recog: */
  275. int
  276. nonindirect_operand (op, mode)
  277.      rtx op;
  278.      enum machine_mode mode;
  279. {
  280.   int retval;
  281.  
  282.   switch (GET_CODE (op))
  283.     {
  284.     case MEM:
  285.       retval = memop_valid (XEXP (op, 0));
  286.       return retval;
  287.     case REG:
  288.       return 1;
  289.     default:
  290.       if (!CONSTANT_P (op))
  291.     return 0;
  292.     }
  293.   return 1;
  294. }
  295.  
  296. /* predicate for the STC instruction: */
  297. int
  298. small_nonneg_const (op, mode)
  299.      rtx op;
  300.      enum machine_mode mode;
  301. {
  302.   if (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) <= 15)
  303.     return 1;
  304.   return 0;
  305. }
  306.  
  307. /* Decide whether to output a conditional jump as a "Jump Conditional"
  308.    or as a "Branch Conditional": */
  309.  
  310. int
  311. find_jmplbl (labelnum)
  312.      int labelnum;
  313. {
  314.   int i, found = 0;
  315.  
  316.   for (i = 0; i <= jmplbl_ndx; i++)
  317.     if (labelnum == jmplbl[i].num)
  318.       {
  319.     found = 1;
  320.     break;
  321.       }
  322.   if (found)
  323.     return i;
  324.   return -1;
  325. }
  326.  
  327. char *
  328. branch_or_jump (condition, targetlabel_number)
  329.      char *condition;
  330.      int targetlabel_number;
  331. {
  332.   static char buf[30];
  333.   int index;
  334.  
  335.   if ((index = find_jmplbl (targetlabel_number)) >= 0)
  336.     if (program_counter - jmplbl[index].pc < 128)
  337.       {
  338.     sprintf (buf, "b%s %%l0", condition);
  339.     return buf;
  340.       }
  341.   sprintf (buf, "jc %s,%%l0", condition);
  342.   return buf;
  343. }
  344.  
  345.  
  346.  
  347. /* The PRINT_OPERAND and PRINT_OPERAND_ADDRESS macros have been
  348.    made functions: */
  349.  
  350. print_operand (file, x, kode)
  351.      FILE *file;
  352.      rtx x;
  353.      enum rtx_code kode;
  354. {
  355.   switch (GET_CODE (x))
  356.     {
  357.     case REG:
  358.       fprintf (file, "%d", REGNO (x));
  359.       break;
  360.     case SYMBOL_REF:
  361.       fprintf (file, "%s", XSTR (x, 0));
  362.       break;
  363.     case LABEL_REF:
  364.     case CONST:
  365.     case MEM:
  366.       output_address (XEXP (x, 0));
  367.       break;
  368.     case CONST_DOUBLE:
  369. /*    {
  370.     double value = get_double (x);
  371.     char fltstr[32];
  372.     sprintf (fltstr, "%lf", value);
  373.  
  374.     if (kode == 'D' || kode == 'E')
  375.       {
  376.         int i, found = 0;
  377.         for (i = 0; i <= datalbl_ndx; i++)
  378.           if (strcmp (fltstr, datalbl[i].value) == 0)
  379.         {
  380.           found = 1;
  381.           break;
  382.         }
  383.         if (!found)
  384.           {
  385.         strcpy (datalbl[i = ++datalbl_ndx].value, fltstr);
  386.         datalbl[i].name = float_label (kode, value);
  387.         datalbl[i].size = (kode == 'E') ? 3 : 2;
  388.         check_section (Konst);
  389.         fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name,
  390.             (kode == 'E' ? "ef" : "f"), fltstr);
  391.         check_section (Normal);
  392.           }
  393.       }
  394.     else if (kode == 'F' || kode == 'G')
  395.       {
  396.         int i, found = 0;
  397.         for (i = 0; i <= datalbl_ndx; i++)
  398.           if (strcmp (fltstr, datalbl[i].value) == 0)
  399.         {
  400.           found = 1;
  401.           break;
  402.         }
  403.         if (!found)
  404.           {
  405.         fprintf (stderr,
  406.            "float value %lfnot found upon label reference\n", value);
  407.         strcpy (datalbl[i = ++datalbl_ndx].value, fltstr);
  408.         datalbl[i].name = float_label (kode, value);
  409.         datalbl[i].size = (kode == 'G') ? 3 : 2;
  410.         check_section (Konst);
  411.         fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name,
  412.             (kode == 'G' ? "ef" : "f"), fltstr);
  413.         check_section (Normal);
  414.           }
  415.         fprintf (file, "%s ;P_O 'F'", datalbl[i].name);
  416.       }
  417.     else
  418.       fprintf (file, " %s  ;P_O cst_dbl ", fltstr);
  419.       }
  420.  */
  421.       fprintf (file, "%lf", get_double (x));
  422.       break;
  423.     case CONST_INT:
  424.       if (kode == 'J')
  425.     fprintf (file, "%d", -INTVAL (x));
  426.       else if (INTVAL (x) > 0x7FFF)
  427.     fprintf (file, "%d  ; range correction (val>0x7FFF) applied",
  428.          INTVAL (x) - 0x10000);
  429.       else
  430.     fprintf (file, "%d", INTVAL (x));
  431.       break;
  432.     case CODE_LABEL:
  433.       fprintf (file, "L%d", XINT (x, 3));
  434.       break;
  435.     case CALL:
  436.       fprintf (file, "CALL nargs=%d, func is either '%s' or '%s'",
  437.        XEXP (x, 1), XSTR (XEXP (XEXP (x, 0), 1), 0), XSTR (XEXP (x, 0), 1));
  438.       break;
  439.     case PLUS:
  440.       {
  441.     rtx op0 = XEXP (x, 0), op1 = XEXP (x, 1);
  442.     int op0code = GET_CODE (op0), op1code = GET_CODE (op1);
  443.     if (op1code == CONST_INT)
  444.       switch (op0code)
  445.         {
  446.         case REG:
  447.           fprintf (file, "%d,r%d  ; p_o_PLUS for REG and CONST",
  448.                INTVAL (op1), REGNO (op0));
  449.           break;
  450.         case SYMBOL_REF:
  451.           fprintf (file, "%d+%s", INTVAL (op1), XSTR (op0, 0));
  452.           break;
  453.         case MEM:
  454.           fprintf (file, "%d,[mem:", INTVAL (op1));
  455.           output_address (XEXP (op0, 0));
  456.           fprintf (file, "] ;P_O plus");
  457.           break;
  458.         default:
  459.           fprintf (file, "p_o_PLUS UFO, code=%d, with CONST=%d",
  460.                (int) op0code, INTVAL (op1));
  461.         }
  462.     else if (op1code == SYMBOL_REF && op0code == REG)
  463.       fprintf (file, "%s,r%d  ; P_O: (plus reg sym)",
  464.            XSTR (op1, 0), REGNO (op0));
  465.     else
  466.       fprintf (file, "p_o_+: op0code=%d, op1code=%d", op0code, op1code);
  467.       }
  468.       break;
  469.     default:
  470.       fprintf (file, "p_o_UFO code=%d", GET_CODE (x));
  471.     }
  472. }
  473.  
  474. print_operand_address (file, addr)
  475.      FILE *file;
  476.      rtx addr;
  477. {
  478.   switch (GET_CODE (addr))
  479.     {
  480.     case REG:
  481.       fprintf (file, "0,r%d ; P_O_A", REGNO (addr));
  482.       break;
  483.     case PLUS:
  484.       {
  485.     register rtx x = XEXP (addr, 0), y = XEXP (addr, 1);
  486.     switch (GET_CODE (x))
  487.       {
  488.       case REG:
  489.         switch (GET_CODE (y))
  490.           {
  491.           case CONST:
  492.         output_address (XEXP (y, 0));
  493.         fprintf (file, ",r%d ;P_O_A reg + const expr", REGNO (x));
  494.         break;
  495.           case CONST_INT:
  496.         fprintf (file, "%d,r%d", INTVAL (y), REGNO (x));
  497.         break;
  498.           case SYMBOL_REF:
  499.         fprintf (file, "%s,r%d  ; P_O_A reg + sym",
  500.              XSTR (y, 0), REGNO (x));
  501.         break;
  502.           case LABEL_REF:
  503.         output_address (XEXP (y, 0));
  504.         fprintf (file, ",r%d  ; P_O_A reg + label", REGNO (x));
  505.         break;
  506.           default:
  507.         fprintf (file, "[P_O_A reg%d+UFO code=%d]",
  508.              REGNO (x), GET_CODE (y));
  509.           }
  510.         break;
  511.       case LABEL_REF:
  512.         output_address (XEXP (x, 0));
  513.         break;
  514.       case SYMBOL_REF:
  515.         switch (GET_CODE (y))
  516.           {
  517.           case CONST_INT:
  518.         fprintf (file, "%d+%s", INTVAL (y), XSTR (x, 0));
  519.         break;
  520.           case REG:
  521.         fprintf (file, "%s,r%d ;P_O_A sym + reg",
  522.              XSTR (x, 0), REGNO (y));
  523.         break;
  524.           default:
  525.         fprintf (file, "P_O_A sym/lab+UFO[sym=%s,code(y)=%d]",
  526.              XSTR (x, 0), GET_CODE (y));
  527.           }
  528.         break;
  529.       case CONST:
  530.         output_address (XEXP (x, 0));
  531.         if (GET_CODE (y) == REG)
  532.           fprintf (file, ",r%d ;P_O_A const + reg", REGNO (x));
  533.         else
  534.           fprintf (file, "P_O_A const+UFO code(y)=%d]", GET_CODE (y));
  535.         break;
  536.       case MEM:
  537.         output_address (y);
  538.         fprintf (file, ",[mem:");
  539.         output_address (XEXP (x, 0));
  540.         fprintf (file, "] ;P_O_A plus");
  541.         break;
  542.       default:
  543.         fprintf (file, "P_O_A plus op1_UFO[code1=%d,code2=%d]",
  544.              GET_CODE (x), GET_CODE (y));
  545.       }
  546.       }
  547.       break;
  548.     case CONST_INT:
  549.       if (INTVAL (addr) < 0x10000 && INTVAL (addr) >= -0x10000)
  550.     fprintf (file, "%d ; p_o_a const addr?!", INTVAL (addr));
  551.       else
  552.     {
  553.       fprintf (file, "[p_o_a=ILLEGAL_CONST]");
  554.       output_addr_const (file, addr);
  555.     }
  556.       break;
  557.     case LABEL_REF:
  558.     case SYMBOL_REF:
  559.       fprintf (file, "%s", XSTR (addr, 0));
  560.       break;
  561.     case MEM:
  562.       fprintf (file, "[memUFO:");
  563.       output_address (XEXP (addr, 0));
  564.       fprintf (file, "]");
  565.       break;
  566.     case CONST:
  567.       output_address (XEXP (addr, 0));
  568.       fprintf (file, " ;P_O_A const");
  569.       break;
  570.     case CODE_LABEL:
  571.       fprintf (file, "L%d", XINT (addr, 3));
  572.       break;
  573.     default:
  574.       fprintf (file, " p_o_a UFO, code=%d val=0x%x",
  575.            (int) GET_CODE (addr), INTVAL (addr));
  576.       break;
  577.     }
  578. }
  579.  
  580.